﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Text;
using System.Threading.Tasks;

namespace VOL.Domain.Infrastructure
{
    public interface IBaseRepository<T> where T : class
    {
        /// <summary>
        /// 插入实体到数据库
        /// </summary>
        /// <param name="t">要插入的实体对象</param>
        /// <returns>受影响的行数</returns>
        Task<int> Add(T t);

        /// <summary>
        /// 更新数据库中的实体
        /// </summary>
        /// <param name="t">包含更新数据的实体对象</param>
        /// <returns>受影响的行数</returns>
        Task<int> Update(T t);

        /// <summary>
        /// 从数据库删除实体
        /// </summary>
        /// <param name="t">要删除的实体对象</param>
        /// <returns>受影响的行数</returns>
        Task<int> Delete(T t);

        /// <summary>
        /// 获取实体集合的查询接口
        /// </summary>
        /// <returns>可查询的实体集合</returns>
        IQueryable<T> GetAll();

        /// <summary>
        /// 获取实体集合的查询接口
        /// </summary>
        /// <returns>可查询的实体集合</returns>
        IQueryable<T> GetAll(Expression<Func<T, bool>> expression);


        /// <summary>
        /// 根据指定属性对实体集合进行去重查询
        /// </summary>
        /// <typeparam name="TKey">去重键的类型</typeparam>
        /// <param name="keySelector">用于选择去重键的表达式</param>
        /// <returns>去重后的可查询集合</returns>
        IQueryable<T> GetDistinctBy<TKey>(Expression<Func<T, TKey>> keySelector);

        /// <summary>
        /// 批量添加/修改实体到数据库
        /// </summary> 
        /// <param name="t">集合</param>
        /// <returns>返回受影响的行数</returns>
        Task<int> CreateRange(IEnumerable<T> t, int? custate);

        /// <summary>
        /// 批量删除实体
        /// </summary>
        /// <param name="t">集合</param>
        /// <returns>返回受影响的行数</returns>
        Task<int> DeleteRang(IEnumerable<T> t);

        /// <summary>
        /// 异步查找符合条件的实体列表
        /// </summary>
        /// <param name="predicate">集合</param>
        /// <returns>返回数据</returns>
        Task<List<T>> FindAsync(Expression<Func<T, bool>> predicate);

        /// <summary>
        /// 根据条件批量删除实体
        /// </summary>
        /// <param name="predicate">删除条件表达式</param>
        /// <returns>返回受影响的行数</returns>
        Task<int> DeleteAsync(Expression<Func<T, bool>> predicate);

        Task<int> AddRange(IEnumerable<T> entities);


        Task<int> UpdateRange(IEnumerable<T> entities);
    }
}
